package com.max.common.controller;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;

import com.max.utils.Constant;
import com.max.utils.PageTitle;
import com.max.utils.ResponseData;
import com.max.utils.ResponseData.ResponseState;
/**
 * 
 * @ClassName BaseController
 * @Description 提供contoller通用的方法
 * @author 陈新建
 * @date 2018年4月23日 下午4:34:21
 */
public abstract class BaseController {

	/**
	 * 模板配置对象
	 */
	//@Resource(name = "freemarkerConfig")
	//private FreeMarkerConfigurer freeMarkerConfigurer;

	/**
	 * 
	 * <p>
	 * <b>方法描述：</b>操作成功默认提示
	 * </p>
	 * 
	 * @return 输出信息的对象
	 */
	protected ResponseData operateSucess() {
		return operateSucess("操作成功");
	}

	/**
	 * 
	 * <p>
	 * <b>方法描述：</b>自定义操作成功提示信息
	 * </p>
	 * 
	 * @param message
	 *            成功时的信息
	 * @return 输出信息的对象
	 */
	protected ResponseData operateSucess(String message) {
		ResponseData result = new ResponseData(ResponseState.SUCESS_STATE);
		result.setMessage(message);
		return result;
	}

	/**
	 * 	
	 * <p>
	 * <b>方法描述：</b>自定义操作成功提示信息，并返回数据
	 * </p>
	 * 
	 * @param message
	 *            成功时的信息
	 * @param data
	 *            数据对象
	 * @return 输出信息的对象
	 */
	protected ResponseData operateSucess(String message, Object data) {
		ResponseData result = operateSucess(message);
		result.setData(data);
		return result;
	}

	/***
	 * <p><b>方法描述：</b>自定义操作成功提示信息，并返回数据和code</p>
	 * @param message 成功时的信息
	 * @param data 数据对象
	 * @param code code编码
	 * @return ResponseData
	 */
	protected ResponseData operateSucess(String message, Object data, String code) {
		ResponseData result = operateSucess(message, data);
		result.setCode(code);
		return result;
	}

	/**
	 * 
	 * <p>
	 * <b>方法描述：</b>自定义失败提示信息
	 * </p>
	 * 
	 * @param message 失败时的信息
	 * @return 输出信息的对象
	 */
	protected ResponseData operateFailed(String message) {
		ResponseData result = new ResponseData(ResponseState.FAILED_STATE);
		result.setMessage(message);
		return result;
	}

	/**
	 * 
	 * <p>
	 * <b>方法描述：</b>自定义失败提示信息并返回数据
	 * </p>
	 * 
	 * @param message 失败时的信息
	 * @param data 数据对象
	 * @return 输出信息的对象
	 */
	protected ResponseData operateFailed(String message, Object data) {
		ResponseData result = operateFailed(message);
		result.setData(data);
		return result;
	}

	/***
	 * <p><b>方法描述：</b>自定义失败提示信息并返回数据和code</p>
	 * @param message 失败时的信息
	 * @param data 数据对象
	 * @param code code编码
	 * @return ResponseData
	 */
	protected ResponseData operateFailed(String message, Object data, String code) {
		ResponseData result = operateFailed(message, data);
		result.setCode(code);
		return result;
	}

	/**
	 * 
	 * <p>
	 * <b>方法描述：</b>获取@Valid校验，返回的全部错误信息
	 * </p>
	 * 
	 * @param result
	 *            校验信息对象
	 * @return 返回全部错误信息
	 */
	protected Map<String, String> getErrors(BindingResult result) {
		Map<String, String> map = new HashMap<String, String>();
		List<FieldError> list = result.getFieldErrors();
		for (FieldError error : list) {
			map.put(error.getField(), error.getDefaultMessage());
		}
		return map;
	}

	/***
	 * 
	 * <p>
	 * <b>方法描述：</b>防止页面重复提交,页面提交成功生，清除token
	 * </p>
	 * 
	 * @param request
	 *            request请求
	 */
	protected void tokenRemove(HttpServletRequest request) {
		request.getSession(false).removeAttribute("token");
	}

	/**
	 * 
	 * <p><b>方法描述：</b>验证是否有错</p>
	 * @param result 校验信息对象
	 * @throws Exception 
	 */
	protected void validation(BindingResult result) throws Exception {
		if (result.hasErrors()) {
			throw new Exception(result.getFieldError().getDefaultMessage());
		}
	}

	/***
	 * 
	 * 
	 * <p><b>方法描述：</b>加载页面初始化信息</p>
	 * @param mav modelAndView
	 * @param page 页面头部对象
	 */
	protected void loadInit(ModelAndView mav, PageTitle page) {
		if (page == null) {
			page = new PageTitle();
		}
		mav.addObject("page", page);
	}

	/***
	 * 
	 * <p>
	 * <b>方法描述：</b>获取ＩＰ地址
	 * </p>
	 * @param request request请求
	 * @return ＩＰ地址
	 */
	public String getIpAddr(HttpServletRequest request) {
		String ip = "";
		if (Constant.PROXY_IP_NAME.isEmpty()) {
			ip = request.getRemoteAddr();
		} else {
			ip = request.getHeader(Constant.PROXY_IP_NAME);
		}
		return ip;
	}
	
	@SuppressWarnings("unchecked")
	public ModelAndView redirect(String redirectUrl,Map<String,Object>...parament){
		ModelAndView view = new ModelAndView(new RedirectView(redirectUrl));
		if(null != parament && parament.length > 0){
			view.addAllObjects(parament[0]);
		}
		return view;
	}

	/**
	 * 
	 * <p>
	 * <b>方法描述：</b><b>后台直接登录方法</b>
	 * </p>
	 * 
	 * @param username
	 *            用户帐号
	 * @param password
	 *            用户密码
	 * @return ResponseData
	 */
	public ResponseData directLogin(String username, String password) {
		ResponseData result;
		try {
			result = new ResponseData(ResponseData.ResponseState.FAILED_STATE);
			Subject currentUser = SecurityUtils.getSubject();
			if (!currentUser.isAuthenticated()) {
				UsernamePasswordToken token = new UsernamePasswordToken(username, password);
				try {
					currentUser.login(token);
					result.setState(ResponseData.ResponseState.SUCESS_STATE.getValue());
				} catch (UnknownAccountException ex) {
					throw new Exception("账号不存在");
				} catch (IncorrectCredentialsException ex) {
					throw new Exception("密码错误");
				} catch (LockedAccountException ex) {
					throw new Exception("账号已被锁定，请与管理员联系");
				} catch (AuthenticationException ex) {
					throw new Exception("您没有授权");
				}
			} else {
				result = new ResponseData(ResponseData.ResponseState.SUCESS_STATE);
				result.setMessage("自动登录成功");
			}
		} catch (Exception e) {
			return operateFailed(e.getMessage());
		}
		return result;
	}

	/**
	 * 
	 * <p><b>方法描述：</b>写入html到response</p>
	 * @param response
	 * @param html
	 * @throws IOException
	 */
	protected void writeToResponse(HttpServletResponse response, String html) throws IOException {
		response.setContentType("text/html;charset=utf-8");
		response.getWriter().print(html);
	}

	/**
	 * 获取页面html
	 * <p><b>方法描述：</b>获取页面html</p>
	 * @param request request对象
	 * @param html 区块html
	 * @return 页面html
	 *//*
	protected String getHtml(HttpServletRequest request, String html) {
		String contentId = request.getParameter("contentId");
		String contentType = request.getParameter("contentType");
		String projectId = request.getParameter("projectId");
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("projectId", projectId);
		paramMap.put("contentId", contentId);
		paramMap.put("userId", UserUtils.getCurrentUserId());
		paramMap.put("contentType", contentType);
		// String pageHtml =
		// HttpClientUtils.httpGetRequest(Constant.getProperty("pageTheme.url",
		// ""), paramMap);
		// if (StringUtils.isBlank(pageHtml)) {
		// try {
		// pageHtml = FreeMarkers.renderString("/struct/struct.htm",
		// getSysStaticParamsMap(), freeMarkerConfigurer.getConfiguration());
		// } catch (IOException | TemplateException e) {
		// e.printStackTrace();
		// }
		// }
		String pageHtml = "";
		try {
			pageHtml = FreeMarkers.renderString("/struct/struct.htm", getSysStaticParamsMap(),
					freeMarkerConfigurer.getConfiguration());
		} catch (Exception e) {
			e.printStackTrace();
		}
		pageHtml = pageHtml.replace("${html!}", html);
		return pageHtml;
	}*/

	protected Map<String, Object> getSysStaticParamsMap() {
		Map<String, Object> staticParamsMap = new HashMap<String, Object>();
		staticParamsMap.put("RootPath", Constant.ROOT_PATH);
		staticParamsMap.put("StaticPath", Constant.STATIC_PATH);
		staticParamsMap.put("JsPath", Constant.JS_PATH);
		return staticParamsMap;
	}
}